package com.extremelylargepackage.editor;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Map.Entry;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import android.content.Context;

import com.extremelylargepackage.FileUtils;
import com.extremelylargepackage.entity.Enemy;
import com.extremelylargepackage.level.Level;
import com.extremelylargepackage.level.LevelEvent;
import com.extremelylargepackage.level.Wave;

public class LevelWriter 
{

	public static void saveLevel(Level l, Context c, File dir) throws IOException
	{
		String xml = writeXml(l);
		FileOutputStream os;
		if(dir == null)
			os = c.openFileOutput(FileUtils.TEST_LEVEL_NAME, Context.MODE_PRIVATE);
		else
			os = new FileOutputStream(new File(dir, l.getName()));
			//os = c.openFileOutput("level/" + l.getName(), Context.MODE_PRIVATE);
		os.write(xml.getBytes());
		os.close();
	}
	
	private static String writeXml(Level l)
	{
		try
		{
			DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = fac.newDocumentBuilder();
			
			Document doc = builder.newDocument();
			
			Element root = getLevelRoot(doc, l);
			for(LevelEvent e : l.getEventQueue())
			{
				if(e instanceof Wave)
				{
					Wave w = (Wave) e;
					if(!w.isDummy())
					{
						root.appendChild(getWaveNode(doc, w));
					}
				}
				else
				{
					//TODO CommandEvent
				}
			}
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer trans = tf.newTransformer();
			
			trans.setOutputProperty(OutputKeys.INDENT, "yes");
			trans.setOutputProperty(OutputKeys.METHOD, "xml");
			StringWriter sw = new StringWriter();
			StreamResult result = new StreamResult(sw);
			DOMSource source = new DOMSource(doc);
			trans.transform(source, result);
			
			return sw.toString();
		}
		catch(Exception e)
		{
			
		}
		return null;
	}
	
	private static Element getLevelRoot(Document doc, Level l)
	{
		Element root = doc.createElement("level");
		doc.appendChild(root);
		
		Attr bg = doc.createAttribute("background");
		bg.setValue("space_nc");
		root.setAttributeNode(bg);
		
		Attr speed = doc.createAttribute("scrollSpeed");
		speed.setValue("" + l.getBackground().getDirY());
		root.setAttributeNode(speed);
		
		return root;
	}
	
	private static Element getWaveNode(Document doc, Wave w)
	{
		Element wave = doc.createElement("wave");
		
		Attr duration = doc.createAttribute("duration");
		duration.setValue(w.getDuration() + "ms");
		wave.setAttributeNode(duration);
		
		for(Entry<Integer, Enemy> e : w.getEnemies().entrySet())
		{
			wave.appendChild(getEnemyNode(doc, e.getKey(), e.getValue()));
		}
		
		return wave;
	}
	
	private static Element getEnemyNode(Document doc, int lane, Enemy e)
	{
		Element enemy = doc.createElement("enemy");
		
		Attr type = doc.createAttribute("type");
		type.setValue(e.getName());
		enemy.setAttributeNode(type);
		
		Attr l = doc.createAttribute("lane");
		l.setValue("" + lane);
		enemy.setAttributeNode(l);
		
		return enemy;
	}
}
